package controllers;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Random;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import models.Filestore;
import models.Sysinfo;
import models.Userlogin;

import rbac.impl.DefaultRbacService;
import rbac.models.Menu;
import rbac.models.Oplog;
import rbac.models.User;
import utils.ConfigUtil;
import utils.Md5Util;

import com.et.mvc.BinaryView;
import com.et.mvc.filter.BeforeFilter;
import com.et.mvc.filter.BeforeFilters;
import com.sun.jimi.core.Jimi;
import com.sun.jimi.core.raster.JimiRasterImage;

@BeforeFilters({
	@BeforeFilter(execute="initRbac", except={"login","logout","error","identifycode"}),
	@BeforeFilter(execute="checkUserPrivilege", except={"login","logout","error","identifycode"})
})
public class HomeController extends ApplicationController {
	public void index() throws Exception {
	    //是否有需要滚动的信息
		List<Sysinfo> infos =  Sysinfo.findAll(Sysinfo.class," passflag = 0 and toroll = 1 and torolldate > getdate() ",null,"id desc");
		request.setAttribute("infos", infos);	
	}
	
	public BinaryView showbackpic() throws Exception{
		User user = (User) rbac.getCurrentUser();
		String fid = ConfigUtil.getConfig(user.getLogin()+"backpicfileid");
		if (fid.equals("")) fid = "0";
		
		Filestore file = Filestore.find(Filestore.class, Integer.parseInt(fid) );
		byte[] data = null;
		if (file != null){
			data = file.getData();
			BinaryView view = new BinaryView();
			view.setData(data);
			view.setContentType("image/jpeg");
			return view;
		}else{
			redirect("/css/images/main.jpg");
			return null;
		}
		
	}
	
	
	private void deleteCookie(){
        Cookie[] cookies = request.getCookies();
        if (cookies != null){
            for(Cookie cookie: cookies){
                if (cookie.getName().equals("sessionId")){
                    cookie.setMaxAge(0);
                    response.addCookie(cookie);
                }
            }
        }
	}
	
	
	
	public void login(String username, String password,String identifycode) throws Exception {
		if (request.getMethod().equalsIgnoreCase("post")){
			String identifycodesession = (String) request.getSession()
					.getAttribute("identifycode");
			// 如果获得的验证码为null，说明验证码过期，必须刷新客户端重新获取
			if (identifycodesession == null) {
				flash.setAttribute("errors", "验证码过期，请刷新验证码！");
				redirect("/home/login");
				return;
			}
			// 输入的验证码不匹配
			if (!identifycode.equalsIgnoreCase(identifycodesession)) {
				flash.setAttribute("errors", "验证码不正确！");
				redirect("/home/login");
				return;
			}
			
			rbac = new DefaultRbacService(request);
			Map<String,Object> result = rbac.login(username, password);
			if (result.get("success") != null){
				deleteCookie();
				Userlogin.AddUserLogin(username, getIpAddr(request) , Md5Util.encodeMD5String(password));
				Cookie c = new Cookie("sessionId", result.get("sessionId").toString());
				c.setMaxAge(240*3600);
				c.setPath(request.getContextPath()); // 对应域名  
				response.addCookie(c);
				Oplog.addMsg(username, result.get("userName") + "("+getIpAddr(request)+")登录系统。");
				redirect("/home/index");
			} else {
				flash.setAttribute("errors", result.get("errors"));
				redirect("/home/login");
			}
		}
	}
	
	public void logout() throws Exception {
		rbac = new DefaultRbacService(request);
		User user = (User) rbac.getCurrentUser();
		rbac.logout();
		deleteCookie();
		Oplog.addMsg(user.getLogin(), user.getName() + "("+getIpAddr(request)+")退出系统。");
		redirect("/home/login");
	}
	
	public void error() {
		
	}
	
	/**
	 * 生成验证码图片 4个
	 * 
	 * @return
	 * @throws Exception
	 */
	private static String codeChars = "0123456789";

	public BinaryView identifycode() throws Exception {
		// 关闭客户端浏览器的缓冲区。
		response.setHeader("ragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setHeader("Expirse", "0");
		// 设置图形大小。
		int width = 90, height = 20;
		// 建立图形缓冲区。
		BufferedImage image = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		Graphics g = image.getGraphics();// 获得 Graphics 对象。
		g.setColor(getRandomColor(180, 250));// 设置背景色。
		g.fillRect(0, 0, width, height);// 填充背景。

		StringBuilder validationCode = new StringBuilder();// 用于保存最后的验证码
		String[] fontNames = { "Times New Roman", "Book antiqua", "Arial" };// 用于随机的字体的集合

		Random r = new Random();
		// 随机生成4-5个验证码
		for (int i = 0; i < 4; i++) {
			g.setFont(new Font(fontNames[r.nextInt(3)], Font.ITALIC, height));
			char codeChar = codeChars.charAt(r.nextInt(codeChars.length()));
			validationCode.append(codeChar);
			g.setColor(getRandomColor(10, 100));
			g.drawString(String.valueOf(codeChar), 16 * i + r.nextInt(7),
					height - r.nextInt(6));// 在图形上输出验证码
		}
		// 随机生干扰码
		for (int i = 0; i < 30; i++) {
			g.setColor(getRandomColor(90, 200));
			int x = r.nextInt(width);
			int y = r.nextInt(height);
			g.drawLine(x, y, x + r.nextInt(10), y + r.nextInt(5));
		}

		session.setMaxInactiveInterval(10 * 60);// 设置session对象10分钟失效。
		session.setAttribute("identifycode", validationCode.toString());// 将验证码保存在session中
		g.dispose();// 关闭Graphics对象

		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		JimiRasterImage raster = Jimi.createRasterImage(image.getSource());
		Jimi.putImage("image/png", raster, outStream);
		outStream.flush();
		outStream.close();

		BinaryView view = new BinaryView();
		view.setData(outStream.toByteArray());
		view.setContentType("image/png");
		return view;
	}

	/**
	 * 生成验证码取得随机颜色
	 * 
	 * @param minColor
	 * @param maxColor
	 * @return
	 */
	private static Color getRandomColor(int minColor, int maxColor) {
		Random r = new Random();
		int red = minColor + r.nextInt(maxColor - minColor);
		int green = minColor + r.nextInt(maxColor - minColor);
		int blue = minColor + r.nextInt(maxColor - minColor);
		return new Color(red, green, blue);
	}
	
}
